﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace ProModel.ApplicationFramework.Silverlight
{
    #region ModalHost Class

    public class ModalHost : UserControl
    {
        #region Fields/Properties

        protected Size _hostSize;
        protected Canvas _backgroundCanvas;
        protected bool _bMouseCapturing = false;
        protected Point _oLastMousePos = new Point();
        internal IModal _modal;

        public Canvas BackgroundCanvas
        {
            get { return _backgroundCanvas; }
            set { _backgroundCanvas = value; }
        }

        public UserControl ChildControl { get { return _modal.HostedControl; } }

        #endregion

        #region Construction

        public ModalHost()
        {
        }

        public ModalHost(IModal control, bool useCanvasPainting)
        {
            _modal = control;
            _backgroundCanvas = new Canvas();
            _backgroundCanvas.Background
                = (useCanvasPainting) ? new SolidColorBrush(Color.FromArgb(100, 0, 0, 0)) : new SolidColorBrush(Colors.Transparent);
            _backgroundCanvas.Children.Add(_modal as UIElement);
            _modal.HostedControl.Height = _backgroundCanvas.Height;            
            Content = _backgroundCanvas;
            Application.Current.Host.Content.Resized += OnHostResized;

            Loaded += OnHostLoaded;
        }

        #endregion

        #region Method Declarations
        
        public virtual void Close()
        {
            Application.Current.Host.Content.Resized -= OnHostResized;
            Loaded -= OnHostLoaded;
            _modal.HostedControl.MouseLeftButtonDown -= OnMouseLeftButtonDown;
            _modal.HostedControl.MouseLeftButtonUp -= OnMouseLeftButtonUp;
            _modal.HostedControl.MouseMove -= OnMouseMove;
            _backgroundCanvas.Children.Clear();
        }

        protected virtual void OnHostLoaded(object sender, RoutedEventArgs e)
        {
            _modal.HostedControl.MouseLeftButtonDown += OnMouseLeftButtonDown;
            _modal.HostedControl.MouseLeftButtonUp += OnMouseLeftButtonUp;
            _modal.HostedControl.MouseMove += OnMouseMove;

            _modal.HostedControl.Focus();
            _modal.HostedControl.TabNavigation = KeyboardNavigationMode.Cycle;

            // Resize background canvas
            // ----------------------------------------
            _backgroundCanvas.Width = WindowHelpers.GetControlSize(_modal as Control).Width;
            _backgroundCanvas.Height = WindowHelpers.GetControlSize(_modal as Control).Height;

            OnHostResized(null, EventArgs.Empty);
            CentreWindow();
        }

        protected virtual void OnHostResized(object sender, EventArgs e)
        {
            _hostSize.Width = Application.Current.Host.Content.ActualWidth;
            _hostSize.Height = Application.Current.Host.Content.ActualHeight;

            // Resize background canvas
            // ----------------------------------------
            //_backgroundCanvas.Width = _oHostSize.Width;
            //_backgroundCanvas.Height = _oHostSize.Height;

            // not ideal, but wtf?
            _backgroundCanvas.Width = _hostSize.Width;
            _backgroundCanvas.Height = _hostSize.Height;
            CentreWindow();
        }

        public virtual void CentreWindow()
        {
            UserControl modal = _modal as UserControl;

            if (_modal != null && !double.IsNaN(WindowHelpers.GetControlSize(modal).Width) 
                && !double.IsNaN(WindowHelpers.GetPanelSize(_backgroundCanvas).Width))
                modal.SetValue(Canvas.LeftProperty, ((WindowHelpers.GetPanelSize(_backgroundCanvas).Width -
                    WindowHelpers.GetControlSize(modal).Width) / 2));

            if (_modal != null && !double.IsNaN(WindowHelpers.GetControlSize(modal).Height) 
                && !double.IsNaN(WindowHelpers.GetPanelSize(_backgroundCanvas).Height))
                modal.SetValue(Canvas.TopProperty, ((WindowHelpers.GetPanelSize(_backgroundCanvas).Height -
                    WindowHelpers.GetControlSize(modal).Height) / 2));
        }

        #endregion

        #region Dragging code

        protected virtual void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _bMouseCapturing = _modal.HostedControl.CaptureMouse();
            _oLastMousePos = e.GetPosition(null);
        }

        protected virtual void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _modal.HostedControl.ReleaseMouseCapture();
            _oLastMousePos = new Point();
            _bMouseCapturing = false;
        }

        protected virtual void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (_bMouseCapturing)
            {
                Point oCurrentMousePos = e.GetPosition(null);
                UserControl modal = _modal as UserControl;

                double dblX = (double)modal.GetValue(Canvas.LeftProperty)
                    + oCurrentMousePos.X - _oLastMousePos.X;

                double dblY = (double)modal.GetValue(Canvas.TopProperty)
                    + oCurrentMousePos.Y - _oLastMousePos.Y;

                if (dblX > 0 && dblX + _modal.HostedControl.ActualWidth < _hostSize.Width)
                    modal.SetValue(Canvas.LeftProperty, dblX);

                if (dblY > 0 && dblY + _modal.HostedControl.ActualHeight < _hostSize.Height)
                    modal.SetValue(Canvas.TopProperty, dblY);

                _oLastMousePos = oCurrentMousePos;
            }
        }
        #endregion
    }

    #endregion
}
